package cn.fl.finance.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import cmm.mid.core.framework.page.DataResultVO;
import cn.cmm.base.framework.utils.*;
import cn.fl.finance.api.IFinPayDtlRApiService;
import cn.fl.finance.condition.FinPayDtlRQC;
import cn.fl.finance.service.IFinPayDtlService;
import cn.fl.finance.transform.FinPayDtlVOTransform;
import cn.fl.finance.vo.FinPayDtlVO;
import cn.fl.project.condition.PrjBscInfoQueryCondition;
import cn.fl.project.condition.PrjPrdPaySchMQueryCondition;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.service.IPrjPrdPaySchMService;
import cn.fl.project.vo.PrjBscInfoVO;
import cn.fl.project.vo.PrjPrdPaySchMVO;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.fl.finance.dto.FinPayDtlRDTO;
import cn.fl.finance.service.IFinPayDtlRService;
import cn.fl.finance.transform.FinPayDtlRVOTransform;
import cn.fl.finance.vo.FinPayDtlRVO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cmm.mid.core.framework.page.Pager;
import cn.cmm.base.framework.exception.BaseException;

/**
 * @Description: 付款明细资产关联表 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class FinPayDtlRServiceImpl implements IFinPayDtlRService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(IFinPayDtlRService.class);
	
	/**
	 * TODO 自定义 API 暴露服务
	 */
	@Autowired
	private IFinPayDtlRApiService finPayDtlRApiService;
	@Autowired
	private IFinPayDtlService finPayDtlService;
	@Autowired
	private IPrjPrdPaySchMService prjPrdPaySchMService;
	@Autowired
	private IPrjBscInfoService prjBscInfoService;
	@Override
	public FinPayDtlRVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		//TODO 业务逻辑
		FinPayDtlRDTO dto = null;//this.自定义ApiService.selectById(id);
		return FinPayDtlRVOTransform.toVO(dto);
	}

	@Override
	public Long add(FinPayDtlRVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增对象不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		//return this.finPayDtlRApiService.add(FinPayDtlRVOTransform.toDTO(entity));
		//TODO 业务逻辑
		return null;
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "removeById", "删除主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		//return this.finPayDtlRApiService.removeById(id);
		//TODO 业务逻辑
		return false;
	}
	
	/**
     * 删除
     * @param ids
     * @return
     */
    public boolean removeByIds(List<Long> ids)throws BaseException{
    	if(CollectionUtils.isEmpty(ids)){
    		BaseLogUtils.info(logger, "removeByIds", "删除主键参数集合不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		};
		return false;
    }

	@Override
	public boolean modify(FinPayDtlRVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", "修改对象参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		//return this.finPayDtlRApiService.modify(FinPayDtlRVOTransform.toDTO(entity));
		//TODO 业务逻辑
		return false;
	}

	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page)page = new Pager();
		//return this.finPayDtlRApiService.searchListPage(page);
		//TODO 业务逻辑
		return null;
	}

	@Override
	public DataResultVO saveAssetBind(String json,Long payDtlId,Double payAmt) {
    	if(StringUtils.isNotBlank(json)){
			FinPayDtlVO payDtlVO = finPayDtlService.selectById(payDtlId);
			// 因为如果用户使用的时候没点击暂存，直接去分配资产，本次申请金额很可能还没有存进数据库 所以通过传参的方式 这样处理。
			payDtlVO.setPayAmt(DecimalUtils.convertYuanToFen(payAmt));
			List<FinPayDtlRDTO> finPayDtlRDTOS = JSON.parseArray(json, FinPayDtlRDTO.class);
			validateYq(finPayDtlRDTOS);
			// 总金额不能大于 paydtl的 本次借款金额
			boolean valide = validate(finPayDtlRDTOS,payDtlVO);
			if(!valide){
				return new DataResultVO(0,"使用金额总额不能大于本次申请金额");
			}
            saveAssetBind(payDtlId, payDtlVO, finPayDtlRDTOS);

        }else{
    		BaseLogUtils.info(logger,"saveAssetBind","error:调用参数为空");
		}
		return new DataResultVO(1,"绑定成功");
	}

	/**
	 * 是否包含疫情贷业务
	 * @param finPayDtlRDTOS
	 */
	private boolean validateYq(List<FinPayDtlRDTO> finPayDtlRDTOS) {
		boolean hasYq = false;
		if(CollectionUtils.isNotEmpty(finPayDtlRDTOS)){
			List<Long> paySchIdList = finPayDtlRDTOS.stream()
					.map(m -> m.getPaySchId())
					.collect(Collectors.toList());
			if(CollectionUtils.isNotEmpty(paySchIdList)){
				PrjPrdPaySchMQueryCondition qc = new PrjPrdPaySchMQueryCondition();
				qc.setIdList(paySchIdList);
				List<PrjPrdPaySchMVO> paySchList = this.prjPrdPaySchMService.searchList(qc);
				if(CollectionUtils.isNotEmpty(paySchIdList)){
					List<Long> prjIdList = paySchList.stream()
							.map(m -> m.getPrjId())
							.collect(Collectors.toList());
					if(CollectionUtils.isNotEmpty(prjIdList)){
						PrjBscInfoQueryCondition qc2 = new PrjBscInfoQueryCondition();
						qc2.setIdList(prjIdList);
						List<PrjBscInfoVO> prjList = this.prjBscInfoService.searchList(qc2);
						if(CollectionUtils.isNotEmpty(prjList)){
							List<String> cntNoList = prjList.stream()
									.filter(vo -> vo.getPrjTypCd() != null && "CDDYWYQ".equals(vo.getPrjTypCd()))
									.map(vo -> vo.getLsCntNo())
									.collect(Collectors.toList());
							if(CollectionUtils.isNotEmpty(cntNoList)){
								throw new BaseException(String.format("不可以绑定YQ业务 %s",JSON.toJSONString(cntNoList)));
							}
						}
					}

				}

			}
		}
		return hasYq;
	}

	/**
     * 保存资产绑定
     * @param payDtlId
     * @param payDtlVO
     * @param finPayDtlRDTOS
     */
    public void saveAssetBind(Long payDtlId, FinPayDtlVO payDtlVO, List<FinPayDtlRDTO> finPayDtlRDTOS) {
        // 金额如果为空要均分剩余金额
        setAmtIfNull(finPayDtlRDTOS,payDtlVO);
        if(CollectionUtils.isNotEmpty(finPayDtlRDTOS) ){
			for (FinPayDtlRDTO finPayDtlRDTO : finPayDtlRDTOS) {
				if(finPayDtlRDTO.getPaySchId()==null){
					throw new BaseException("保存失败，部分数据支付表ID为空,请重试。");
				}
			}
            // 删除
            finPayDtlRApiService.deleteByPayDtlId(payDtlId);
            for (FinPayDtlRDTO finPayDtlRDTO : finPayDtlRDTOS) {
                finPayDtlRDTO.setPayDtlId(payDtlId);
            }
            // 插入
            finPayDtlRApiService.batchAdd(finPayDtlRDTOS);
        }
    }

    /**
	 * 如果使用金额为0，则将使用金额均摊到资产
	 * @param list
	 * @param payDtlVO
	 */
	private void setAmtIfNull(List<FinPayDtlRDTO> list, FinPayDtlVO payDtlVO) {
		if(CollectionUtils.isNotEmpty(list)){
			boolean flag = false; //是否要进行分摊
			Long total = payDtlVO.getPayAmt();
			Long sum = 0l;
			for (FinPayDtlRDTO finPayDtlRDTO : list) {
				Long payAmt = finPayDtlRDTO.getPayAmt();
				sum += payAmt;
				if(payAmt == 0l){
					flag=true;
				}
			}
			if(!total.equals(sum)){ // 不相等也执行均摊
				flag = true;
			}
			if(flag){
				long avg = total/ list.size(); // 平均每个分多少
				for (int i = 0; i < list.size()-1; i++) {
					total -= avg;
					FinPayDtlRDTO finPayDtlRDTO = list.get(i);
					finPayDtlRDTO.setPayAmt(avg);
				}
				FinPayDtlRDTO lastOne = list.get(list.size() - 1);
				lastOne.setPayAmt(total);
			}
		}
	}

	/**
	 * 总金额不能大于 payDtlVO 本次借款金额
	 * @param list
	 * @param vo
	 */
	private boolean validate(List<FinPayDtlRDTO> list, FinPayDtlVO vo) {
		Long total = 0l;
		if(CollectionUtils.isNotEmpty(list)){
			for (FinPayDtlRDTO dto : list) {
				total += dto.getPayAmt();
			}
			if(total <= vo.getPayAmt()){
				return true;
			}
		}
		return false;
	}

	@Override
	public List<FinPayDtlRVO> selectList(FinPayDtlRQC qc) {
		return FinPayDtlRVOTransform.toVOList(this.finPayDtlRApiService.selectList(qc));
	}

	@Override
	public void deleteByIdList(List<String> idList) {
		this.finPayDtlRApiService.deleteByIdList(idList);
	}
}
